package com.njtoyo.taxi.admin.cmb;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.njtoyo.taxi.admin.library.payment.cmb.CmbPayClient;
import com.njtoyo.taxi.admin.library.payment.common.CmbRefundInfo;
import com.njtoyo.taxi.admin.logic.business.ride.RideLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.CallPrepayOrder;
import com.njtoyo.taxi.admin.mapper.master.entity.CallPrepayOrderRefundLog;
import com.njtoyo.taxi.admin.mapper.master.entity.Ride;
import com.njtoyo.taxi.admin.mapper.master.entity.RideOrder;
import com.njtoyo.taxi.admin.mapper.master.mapper.CallPrepayOrderMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.CallPrepayOrderRefundLogMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.RideMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@SpringBootTest
@ActiveProfiles(value = "prod")
public class Refund {

    @Autowired
    private RideMapper rideMapper;
    @Autowired
    private RideLogic rideLogic;
    @Autowired
    private CallPrepayOrderMapper callPrepayOrderMapper;
    @Autowired
    private CallPrepayOrderRefundLogMapper callPrepayOrderRefundLogMapper;
    private static final Long rideId = Convert.toLong(859992);
    private static final BigDecimal refundAmount = new BigDecimal("144.9");


    /**
     * TODO 预付单退款
     * 2024年12月12日14:42:59 目前只支持有补钱的
     *
     * @throws Exception
     */
    @Test
    public void refund() throws Exception {
        log.info(String.format("发起招商退款"));
        Ride ride = rideMapper.selectById(rideId);
        RideOrder order = rideLogic.getPaidOrderByRideId(rideId);
        Integer willRefundAmount = Convert.toInt(refundAmount.multiply(new BigDecimal(100)).intValue());
        if (ObjectUtil.isNotNull(order.getPrepayAmount()) && order.getPrepayAmount().compareTo(BigDecimal.ZERO) == 1) {//预付款订单
            CallPrepayOrder callPrepayOrder = callPrepayOrderMapper.selectOne(Wrappers.<CallPrepayOrder>lambdaQuery()
                    .eq(CallPrepayOrder::getCallCategory, ride.getCategory().getCode()).
                    eq(CallPrepayOrder::getCallId, ride.getRefId()));
            BigDecimal addAmount = order.getFarePaid();
            if (addAmount.compareTo(BigDecimal.ZERO) == 1) {//有补钱操作
                //补的钱
                Integer addAmountInt = addAmount.multiply(new BigDecimal(100)).intValue();
                //计算后续补的钱是否够退款的
                //TODO 先从补充的中退
                Map<String, String> resultAddAmount = CmbPayClient.refund(getRefundId(), order.getNumber(), "退款", order.getNumber(), getRefundId(),
                        addAmountInt.toString(), willRefundAmount > addAmountInt ? addAmountInt.toString() : willRefundAmount.toString());
                log.info("退招商退预付款补充的钱返回--结果：{}", resultAddAmount);
                String errCodeAddAmount = MapUtil.getStr(resultAddAmount, "errCode");
                if (StrUtil.isNotBlank(errCodeAddAmount)) {
                    String respMsg = MapUtil.getStr(resultAddAmount, "respMsg");
                    log.error("订单RideOrder：{},招商退预付款补充的钱返回--失败,失败原因：{}", order, respMsg);
                } else {
                    log.info("订单RideOrder：{},招商退预付款补充的钱返回--成功,开始执行退预付款");
                    //判断退款金额是否大于补充的
                    if (willRefundAmount > addAmountInt) {//不够退的
                        //TODO 不够退的继续从预付中减
                        //差额
                        Integer refundAmountDifference = willRefundAmount - addAmountInt;
                        //差额继续从预付中减
                        Integer preAmountInt = order.getPrepayAmount().multiply(new BigDecimal(100)).intValue();
                        Map<String, String> resultPreAmount = CmbPayClient.refund(getRefundId(), callPrepayOrder.getNumber(), "退款", callPrepayOrder.getNumber(),
                                getRefundId(), preAmountInt.toString(), refundAmountDifference.toString());
                        log.info("退招商退预付款返回--结果：{}", resultPreAmount);
                        String respPreCode = MapUtil.getStr(resultPreAmount, "respCode");
                        if (!"SUCCESS".equals(respPreCode)) {
                            String respMsg = MapUtil.getStr(resultPreAmount, "respMsg");
                            log.error("招商退预付款返回--失败,失败原因：{}", order, respMsg);
                        } else {
                            log.info("招商退预付款返回--成功");
                        }
                    }
                }
            } else {//无补钱操作
                List<CallPrepayOrderRefundLog> callPrepayOrderRefundLogs = callPrepayOrderRefundLogMapper.selectList(Wrappers.<CallPrepayOrderRefundLog>lambdaQuery()
                        .eq(CallPrepayOrderRefundLog::getOrderId, callPrepayOrder.getId()).eq(CallPrepayOrderRefundLog::getIsSuccess, true));
                BigDecimal reduce = callPrepayOrderRefundLogs.stream().map(CallPrepayOrderRefundLog::getRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal willRefund = NumberUtil.sub(callPrepayOrder.getAmount(), reduce);
                if (willRefund.compareTo(BigDecimal.ZERO) == 1) {
                    String resultPreAmountStr = Convert.toStr(willRefund.multiply(new BigDecimal(100)).intValue());
                    String txnAmtStr = Convert.toStr(callPrepayOrder.getAmount().multiply(new BigDecimal(100)).intValue());
                    Map<String, String> resultRefundAmount = CmbPayClient.refund(getRefundId(), callPrepayOrder.getNumber(), "退款", callPrepayOrder.getNumber(), getRefundId(), txnAmtStr, resultPreAmountStr);
                    String errCodeRefundAmount = MapUtil.getStr(resultRefundAmount, "errCode");
                    if (StrUtil.isNotBlank(errCodeRefundAmount)) {
                        String respMsg = MapUtil.getStr(resultRefundAmount, "respMsg");
                        log.info("订单RideOrder：{},招商退预付款补充的钱返回--失败,失败原因：{}", order, respMsg);
                    }else{
                        String respPreCode = MapUtil.getStr(resultRefundAmount, "respCode");
                        if ("SUCCESS".equals(respPreCode)) {
                            log.info("订单RideOrder：{},招商退预付款返回--成功", order);
                            //保存预付款的退款记录
                            callPrepayOrderRefundLogMapper.insert(new CallPrepayOrderRefundLog()
                                    .setOrderId(callPrepayOrder.getId())
                                    .setIsSuccess(true)
                                    .setRefundAmount(willRefund)
                                    .setRefundNumber(callPrepayOrder.getNumber()));
                            //修改预付款退款状态
                            callPrepayOrderMapper.updateById(new CallPrepayOrder().setId(callPrepayOrder.getId()).setIsRefund(true));
                            //修改订单退款状态
                        }
                    }

                }

            }
        }
    }

    private String getRefundId() {
        return IdUtil.getSnowflake(1, 1).nextIdStr();
    }
}
